package AlexDB.Command;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import AlexDB.MDB.DataBase;

public abstract class BaseCommand<T extends Map<?,?>>  implements IDbCommandType  {
    T map;
    public BaseCommand(){
        map = getDataBaseMap();
        if(map == null)
        {
            Type superclass = getClass().getGenericSuperclass();
            try {
                map = (T)superclass.getClass().getDeclaredConstructor().newInstance();
                putToDataMap();
            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException | NoSuchMethodException | SecurityException e) {
                // e.printStackTrace();
            }
        }
    }
    
    protected T getDataBaseMap()
    {
       return (T)DataBase.getDb().getDbMapObj(this.getClass());
    }
    
    protected void putToDataMap()
    {
        DataBase.getDb().putDbMapObj(this.getClass(), map);
    }

    public T getDataMap()
    {
        return map;
    }

    protected Method getInvokeMethod(String annonValue) throws Exception
    {
        Method[] thisMethods = this.getClass().getDeclaredMethods();

        var callMethods = 
        Arrays.asList(thisMethods).stream().filter(item -> 
        item.getAnnotations().length > 0 && item.getAnnotation(CommandOperationAttribute.class).value().equals(annonValue))
        .collect(Collectors.toList());
        
        if(callMethods.size() > 1)
            throw new Exception("service resolve error: methods route repetition.");
        else if(callMethods.size() <= 0)
            throw new Exception("service resolve command error: not find operation.");
        return callMethods.get(0);
    }

}
